/* 
 * map-functions.js
 */

var map;
var bounds;
var direction;
var default_lat = 48.8566140;
var default_lng = 2.3522219;
var default_image = "img/marker-default.svg";
var default_icon_width = 32;
var default_icon_height = 32;
var default_icon_anchor_x = default_icon_width / 2;
var default_icon_anchor_y = default_icon_height;
var addMarkerWindow = null;
var editInfoWindow = null;
var markerIndex = 1;
var itineraryIndex = 1;
var markers = new Array();
var markerList = null;
var itineraries = new Array();
var geocoder;
var searchResult = new Array();
var itineraireDefaut = null;
var colors = new Array();
var itineraireDefautEvents = new Array();
var marqueurs = null;
var markersForName = new Array();
var eventsForName = new Array();
var polylineForName = null;
var polylines = new Array();
var events = new Array();

/**
 * Initialisation de la carte
 * 
 * @param {Real} lat
 * @param {Real} lng
 * @returns {Boolean}
 */
function mapInitialise(lat, lng) {
    lat = (!lat) ? default_lat : lat;
    lng = (!lng) ? default_lng : lng;
    var div = document.getElementById('map');
    var center = new google.maps.LatLng(lat, lng);
    var options = {
        center: center,
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(div, options);
    bounds = new google.maps.LatLngBounds();
    // Ajouter un événement click
    google.maps.event.addListener(map, 'click', function(event) {
        clickMap(event.latLng);
    });
    console.log('Initialisation de la carte');
    // Instanciation du Direction Renderer
    var panel = document.getElementById('panel');
    direction = new google.maps.DirectionsRenderer({
        map: map,
        panel: panel
    });
    // Instanciation du geocoder
    geocoder = new google.maps.Geocoder();
    // Initialisation des couleurs
    initializeColor();
    return false;
}

/**
 * Click sur la carte
 * 
 * @param {latLng} latLng
 * @returns {Boolean}
 */
function clickMap(latLng) {
    console.log('Clic sur la carte');
    if (editInfoWindow) {
        editInfoWindow.close();
    }
    if (addMarkerWindow) {
        addMarkerWindow.close();
    }
    var $ajax = $.ajax({
        type: 'post',
        url: 'marker-add.php',
        data: '&lat=' + latLng.lat() + '&lng=' + latLng.lng()
    });
    $ajax.done(function(data) {
        addMarkerWindow = new google.maps.InfoWindow({
            position: latLng,
            content: data
        });
        addMarkerWindow.open(map);
        console.log("Ouverture du InfoWindow d'ajout de marqueur");
    });
    return false;
}

/**
 * Fermer le addMarkerWindow
 * 
 * @returns {Boolean}
 */
function closeAddMarkerWindow() {
    console.log("Ferméture du InfoWindow d'ajout de marqueur ");
    addMarkerWindow.close();
    return false;
}

/**
 * Ajouter un marqueur
 * 
 * @param {latLng} latLng
 * @param {Integer} image
 * @param {String} title
 * @returns {Boolean}
 */
function addMarker(latLng, image, title) {
    console.log("Ajouter Marqueur : " + title);
    image = (!image) ? default_image : image;
    var index = markerIndex;
    title = (!title) ? 'Marqueur #' + index : title;
    var marker = new google.maps.Marker({
        position: latLng,
        map: map,
        draggable: true,
        icon: image,
        title: title,
        animation: google.maps.Animation.DROP
    });
    // Ajouter les informations sur la gauche
    addMarkerInfo(index, title, latLng.lat(), latLng.lng(), image);
    markers[index] = marker;
    // Mise à jour de l'itinéraire par défaut
    editDefaultItinerary();
    // Ajouter un événement Click pour l'édition
    google.maps.event.addListener(marker, 'click', function(event) {
        console.log("Click sur le marqueur");
        var $ajax = $.ajax({
            type: 'post',
            url: 'marker-edit.php',
            data: '&index=' + index + '&title=' + encodeURI($('#marker-' + index + ' #marker-title').val())
        });
        $ajax.done(function(data) {
            if (editInfoWindow) {
                editInfoWindow.close();
            }
            if (addMarkerWindow) {
                addMarkerWindow.close();
            }
            editInfoWindow = new google.maps.InfoWindow({
                content: data
            });
            editInfoWindow.open(map, marker);
        });
    });
    // Ajouter un événement DragEnd pour mettre à jour les informations
    google.maps.event.addListener(marker, 'dragend', function(event) {
        console.log("Fin du déplacement du marqueur #" + index);
        editMarkerPosition(event.latLng, index);
    });
    // Etendre les limites de la carte
    bounds.extend(latLng);
    map.fitBounds(bounds);
    console.log("Ajout du marqueur [" + markerIndex++ + "] au coordonnées : " + latLng.lat() + ", " + latLng.lng());
    return false;
}

/**
 * Ajouter les informations du marqueurs
 * 
 * @param {Integer} index
 * @param {String} title
 * @param {Real} lat
 * @param {Real} lng
 * @param {String} img
 * @returns {Boolean}
 */
function addMarkerInfo(index, title, lat, lng, img) {
    var $ajax = $.ajax({
        type: 'post',
        url: 'marker-info.php',
        data: '&index=' + index + '&title=' + encodeURI(title) + '&lat=' + lat + '&lng=' + lng + '&img=' + encodeURI(img)
    });
    $ajax.done(function(data) {
        $('#marker-list').append(data);
    });
    return false;
}

/**
 * Editer la position du Marqueur
 * 
 * @param {LatLng} latLng
 * @param {Integer} index
 * @returns {Boolean}
 */
function editMarkerPosition(latLng, index) {
    $('#marker-' + index + ' #marker-lat').val(latLng.lat());
    $('#marker-' + index + ' #marker-lng').val(latLng.lng());
    return false;
}

/**
 * Editer l'icone du Marqueur
 * 
 * @param {String} image
 * @param {Integer} index
 * @returns {Boolean}
 */
function editMarkerIcon(image, index) {
    var marker = markers[index];
    marker.setIcon(image);
    $('#marker-' + index + ' #marker-icon img').attr('src', image);
    return false;
}

/**
 * Edition du titre du marqueur
 * 
 * @param {type} title
 * @param {type} index
 * @returns {Boolean}
 */
function editMarkerTitle(title, index) {
    var marker = markers[index];
    marker.setTitle(title);
    $('#marker-' + index + ' #marker-title').val(title);
    editDefaultItinerary();
    return false;
}

/**
 * Effacer un Marqueur
 * 
 * @param {Integer} index
 * @returns {Boolean}
 */
function removeMarker(index){
    if(!confirm("Voulez-vous effacer ce Marqueur ?")){
        return false;
    }
    var marker = markers[index];
    marker.setMap(null);
    $('#marker-' + index).hide('normal', function(){
        $(this).remove();
    });
    return false;
}

/**
 * Créer les informations d'icone
 * 
 * @param {String} image
 * @param {Integer} w
 * @param {Integer} h
 * @param {Integer} x
 * @param {Integer} y
 * @returns {createIcon.icon}
 */
function createIcon(image, w, h, x, y) {
    w = (!w) ? default_icon_width : w;
    h = (!h) ? default_icon_height : h;
    x = (!x) ? default_icon_anchor_x : x;
    y = (!y) ? default_icon_anchor_y : y;

    var size = new google.maps.Size(w, h);
    var origin = new google.maps.Point(0, 0);
    var anchor = new google.maps.Point(x, y);
    var icon = {
        url: image,
        size: size,
        origin: origin,
        anchor: anchor
    };
    return icon;
}

/**
 * Créer un LatLng
 * 
 * @param {Real} lat
 * @param {Real} lng
 * @returns {google.maps.LatLng}
 */
function createLatLng(lat, lng) {
    var latLng = new google.maps.LatLng(lat, lng);
    console.log(latLng);
    return latLng;
}

/**
 * Liste des marqueurs
 * 
 * @returns {Array}
 */
function getMarkers(){
    var list = new Array();
    var idx = 0;
    for(var i = 1; i < markerIndex; i++){
        //console.log(i);
        var m = markers[i];
        //console.log(m);
        list[idx++] = m;
    }
    //console.log(list);
    markerList = list;
    return list;
}

function addItinerary(){
    var $ajax = $.ajax({
        type: 'post',
        url : 'itinerary-new.php',
        data: '&index=' + itineraryIndex++
    });
    $ajax.done(function(data){
        $('#footer').append(data);
    });
}

/**
 * Coordonnées du point
 * 
 * @param {Integer} id
 * @returns {LatLng}
 */
function getItineraryLatLng(id){
    var m = markerList[id];
    console.log(id);
    console.log(m);
    console.log(markerList);
    return m.getPosition();
}

/**
 * Edition des itinéraires par défaut
 * 
 * @returns {undefined}
 */
function editDefaultItinerary(){
    var count = markers.length;
    console.log("Il y a " + count + " marqueurs");
    console.log(markers);
    var first = markers[1];
    var last = markers[count-1];
    $('#defaut-depart').text(first.getTitle());
    $('#defaut-arrivee').text(last.getTitle());
}

/**
 * Dessiner l'itinéraire par défaut
 * 
 * @param {type} type
 * @returns {google.maps.Polyline}
 */
function drawDefaultItinerary(type){
    var color = colors[type];
    var marks = new Array();
    marqueurs = new Array();
    var count = markers.length;
    for(var i = 0; i < count - 1; i++){
        var marker = markers[i + 1];
        marqueurs[i] = marker;
        marks[i] = marker.getPosition();
    }
    if(itineraireDefaut){
        itineraireDefaut.setMap(null);
        itineraireDefaut = null;
    }
    itineraireDefaut = new google.maps.Polyline({
        map: map,
        path: marks,
        strokeColor: color,
        strokeOpacity: 0.5,
        strokeWeight: 5
    });
    count = marqueurs.length;
    //console.log(marqueurs);
    removeDefaultItineraryEvent();
    for(var i = 0; i < count; i++){
        var marker = marqueurs[i];
        //console.log("Index " + i);
        //console.log(marker);
        // Add Event Listener
        //console.log(marker);
        try{
            itineraireDefautEvents[i] = createDragEndEventForDefaultItinerary(i);
            if(!itineraireDefautEvents[i]){
                throw "Itinéraire est vide ou NULL";
            }
        }catch (ex){
            console.log(ex);
        }
        //console.log("Ajout de nouveau listener pour l'itinéraire par défaut au marqueur " + marker.getTitle());
        //console.log(itineraireDefautEvents[i]);
    }
    //console.log(itineraireDefautEvents);
    return itineraireDefaut;
}

/**
 * Effacer tous les événements stockés dans la map par défaut
 * 
 * @returns {undefined}
 */
function removeDefaultItineraryEvent(){
    var count = itineraireDefautEvents.length;
    for(var k = 0; k < count; k++){
        google.maps.event.removeListener(itineraireDefautEvents[k]);
    }
    itineraireDefautEvents = new Array();
}

/**
 * Initialisation des couleurs
 * 
 * @returns {undefined}
 */
function initializeColor(){
    colors[0] = '#ff3333'; // Avion
    colors[1] = '#009900'; // Randonnées
    colors[2] = '#0066ff'; // Bateau
}

/**
 * Créer un MapEventListener
 * 
 * @param {Integer} index
 * @returns {google.maps.event.addListener}
 */
function createDragEndEventForDefaultItinerary(index){
    var marker = marqueurs[index];
    //console.log(marker);
    var dragEnd = new google.maps.event.addListener(marker, 'dragend', function(){
        //console.log("Déplacement du marqueur " + marker.getTitle());
        //console.log("Redessiner l'itinéraire par défaut");
        drawDefaultItinerary(parseInt($('#defaut-type').val()));
    });
    return dragEnd;
}

/**
 * Récupérer les noms
 * 
 * @returns {getNames.tab|String}
 */
function getNames(){
    var text = $('#itinerary-name').val();
    console.log(text);
    var reg = new RegExp("[;]+", "g");
    var tab = text.split(reg);
    console.log(tab);
    var count = tab.length;
    for(var i = 0; i < count; i++){
        tab[i] = $.trim(tab[i]);
    }
    return tab;
}

function drawPolyLinesForName(type){
    console.log(markersForName);
    var color = colors[type];
    var count = markersForName.length;
    var path = new Array();
    emptyEventsName();
    for(var i = 0; i < count; i++){
        var marker = markersForName[i];
        path[i] = marker.getPosition();
        // Evenement
        eventsForName[i] = google.maps.event.addListener(marker, 'dragend', function(){
            drawPolyLinesForName(parseInt($('#name-type').val()));
        });
    }
    console.log(path);
    if(polylineForName){
        polylineForName.setOptions({
            path: path,
            color: color
        });
    }else{
        polylineForName = new google.maps.Polyline({
            map: map,
            path: path,
            strokeColor: color,
            strokeOpacity: 0.5,
            strokeWeight: 5
        });
    }
}

/**
 * Effacer les tablaux
 * 
 * @returns {undefined}
 */
function emptyTheNames(){
    var count = markersForName.length;
    for(var i = 0; i < count; i++){
        markersForName.shift();
    }
}

function emptyEventsName(){
    var count = eventsForName.length;
    for(var i = 0; i < count; i++){
        google.maps.event.removeListener(eventsForName[i]);
        eventsForName.shift();
    }
}

function drawPolyline(startId, endId, type){
    var color = colors[type];
    var markerStart = markers[startId];
    var markerEnd = markers[endId];
    var path = [markerStart.getPosition(), markerEnd.getPosition()];
    var index = polylines.length;
    var polyline = new google.maps.Polyline({
        map : map,
        path: path,
        strokeColor: color,
        strokeOpacity: 0.5,
        strokeWeight: 5
    });
    polylines[index] = polyline;
    // Evénements
    var eventStart = google.maps.event.addListener(markerStart, 'dragend', function(){
        redrawPolyline(index, markerStart, markerEnd);
    });
    var eventEnd = google.maps.event.addListener(markerEnd, 'dragend', function(){
        redrawPolyline(index, markerStart, markerEnd);
    });
    events[index] = new Array();
    events[index][0] = eventStart;
    events[index][1] = eventEnd;
}

function redrawPolyline(index, start, end){
    // Empty events
    google.maps.event.removeListener(events[index][0]);
    google.maps.event.removeListener(events[index][1]);
    var path = [start.getPosition(), end.getPosition()];
    polylines[index].setPath(path);
    // Evénements
    var eventStart = google.maps.event.addListener(markerStart, 'dragend', function(){
        redrawPolyline(index, start, end);
    });
    var eventEnd = google.maps.event.addListener(markerEnd, 'dragend', function(){
        redrawPolyline(index, start, end);
    });
    events[index][0] = eventStart;
    events[index][1] = eventEnd;
}